package com.xci.core.domain;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

import java.util.Arrays;
import java.util.List;

/**
 * 封装布尔消息，消息中封装两个字段：一个表示操作是否成功，一个表示操作消息
 * @author 吕艳阳
 */
@ApiModel(description = "执行结果")
public class BoolMessage<E>{
    /**
     * 是否成功
     */
    @ApiModelProperty(value = "状态")
    private boolean success;

    /**
     * 消息文本
     */
    @ApiModelProperty(value = "状态消息")
    private String msg;

    /**
     * 数据对象
     */
    @ApiModelProperty(value = "数据对象")
    private E data;

    /**
     * 从指定的布尔状态和状态消息来初始化布尔消息
     * @param success 是否成功
     * @param msg     消息文本
     * @param data    数据对象
     */
    private BoolMessage(boolean success, String msg, E data) {
        this.success = success;
        this.msg = msg;
        this.data = data;
    }

    /**
     * 成功消息
     * @return 返回成功消息
     */
    public static <R> BoolMessage<R> success() {
        return new BoolMessage<>(true, null, null);
    }

    /**
     * 成功消息
     * @param data 数据对象
     * @return 返回成功消息
     */
    public static <R> BoolMessage<R> success(R data) {
        return new BoolMessage<>(true, null, data);
    }

    /**
     * 成功消息
     * @param msg  消息文本
     * @return 返回成功消息
     */
    public static <R> BoolMessage<R> success(String msg) {
        return new BoolMessage<>(true, msg, null);
    }

    /**
     * 合并消息
     * @param msgs 多个消息
     * @return 返回合并后的消息对象
     */
    public static BoolMessage merge(BoolMessage... msgs) {
        if (msgs == null || msgs.length == 0) {
            return new BoolMessage<>(true,null,null);
        }
        return merge(Arrays.asList(msgs));
    }

    /**
     * 合并消息
     * @param msgs 多个消息
     * @return 返回合并后的消息对象
     */
    public static BoolMessage merge(List<BoolMessage> msgs) {
        if (msgs == null || msgs.size() == 0) {
            return new BoolMessage<>(true,null,null);
        }
        boolean success = true;
        StringBuilder message = new StringBuilder();
        for (BoolMessage current : msgs) {
            if (current == null)
                continue;
            success = success && current.isSuccess();
            if (current.getMsg() != null && !current.getMsg().equals("")) {
                message.append(current.getMsg()).append(";");
            }
        }
        return new BoolMessage<>(success, message.deleteCharAt(message.length() - 1).toString(),null);
    }

    /**
     * 成功消息
     * @param msg  消息文本
     * @param data 数据对象
     * @return 返回成功消息
     */
    public static <R> BoolMessage<R> success(String msg, R data) {
        return new BoolMessage<>(true, msg, data);
    }

    /**
     * 失败消息
     * @return 返回失败消息
     */
    public static <R> BoolMessage<R> fail() {
        return new BoolMessage<>(false, null, null);
    }

    /**
     * 失败消息
     * @param msg 消息文本
     * @return 返回失败消息
     */
    public static <R> BoolMessage<R> fail(String msg) {
        return new BoolMessage<>(false, msg, null);
    }

    /**
     * 失败消息
     * @return 返回失败消息
     */
    public static <R> BoolMessage<R> fail(R data) {
        return new BoolMessage<>(false, null, data);
    }

    /**
     * 失败消息
     * @param msg 消息文本
     * @return 返回失败消息
     */
    public static <R> BoolMessage<R> fail(String msg, R data) {
        return new BoolMessage<>(false, msg, data);
    }

    /**
     * 结果消息
     */
    public static <R> BoolMessage<R> result(boolean result) {
        return new BoolMessage<>(result, null, null);
    }

    /**
     * 结果消息
     */
    public static <R> BoolMessage<R> result(boolean result, String msg) {
        return new BoolMessage<>(result, msg, null);
    }

    /**
     * 结果消息
     */
    public static <R> BoolMessage<R> result(boolean result, R data) {
        return new BoolMessage<>(true, null, data);
    }

    /**
     * 结果消息
     */
    public static <R> BoolMessage<R> result(boolean result, String msg, R data) {
        return new BoolMessage<>(true, msg, data);
    }

    public boolean isSuccess(){
        return success;
    }

    @JsonIgnore
    public boolean isFail(){
        return !success;
    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public String getMsg() {
        return msg;
    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public E getData() {
        return data;
    }
}